package service

import (
	"awesomeProject/app/model"
	"awesomeProject/app/request"
	"awesomeProject/app/response"
	"awesomeProject/global"
	"awesomeProject/util"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"strings"
	"time"

	"context"
	"fmt"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"strconv"
)

type RefundSrv struct{}

func (r *RefundSrv) Pagination(req request.RefundPagination, shopIds []uint, operator model.User) response.Resp {
	filter := bson.D{
		bson.E{Key: "confirmType", Value: req.ConfirmType},
	}
	if req.ShopId != 0 {
		filter = append(filter, bson.E{Key: "shopId", Value: req.ShopId})
	} else {
		if req.CompanyId != 0 && operator.SuperAdmin {
			var accounts []model.Account
			err := global.Gorm.Where("company_id=? and status=1", req.CompanyId).Find(&accounts).Error
			if err != nil {
				return response.ErrQuery
			}
			shopIds = []uint{}
			for _, account := range accounts {
				shopIds = append(shopIds, account.ShopId)
			}
		}
		if len(shopIds) > 0 {
			filter = append(filter, bson.E{Key: "shopId", Value: bson.M{"$in": shopIds}})
		}
	}
	if req.SkuTypeValue != "" {
		if req.SkuType == "skuId" {
			filter = append(filter, bson.E{Key: "skuId", Value: req.SkuTypeValue})
		} else if req.SkuType == "skuNo" {
			filter = append(filter, bson.E{Key: "skuNo", Value: req.SkuTypeValue})
		} else if req.SkuType == "itemId" {
			filter = append(filter, bson.E{Key: "itemId", Value: req.SkuTypeValue})
		} else if req.SkuType == "itemNo" {
			filter = append(filter, bson.E{Key: "itemNo", Value: req.SkuTypeValue})
		}
	}
	//if req.WarehouseId != 0 {
	//	filter = append(filter, bson.E{Key: "warehouseId", Value: req.WarehouseId})
	//}
	if req.ExternalOrderType != 0 {
		filter = append(filter, bson.E{Key: "externalOrderType", Value: req.ExternalOrderType})
	}
	if req.ReturnAddress != "" {
		filter = append(filter, bson.E{Key: "returnAddress", Value: bson.M{"$regex": primitive.Regex{Pattern: ".*"+strings.Trim(req.ReturnAddress, " ")+".*", Options: "i"}}})
	}
	offset := (req.PageIndex - 1) * req.PageSize
	match := bson.D{{"$match", filter}}
	fmt.Println(match)
	sort := bson.D{{"$sort", bson.M{"joinReturnDate": -1}}}
	skip := bson.D{{"$skip", offset}}
	limit := bson.D{{"$limit", req.PageSize}}
	cursor, err := global.MongoDB.Collection("refunds").Aggregate(context.TODO(), mongo.Pipeline{match, sort, skip, limit})
	if err != nil {
		return response.ErrQuery
	}
	var refunds []map[string]interface{}
	if err = cursor.All(context.TODO(), &refunds); err != nil {
		return response.ErrQuery
	}
	if len(refunds) == 0 {
		return response.OK.WithData(map[string]interface{}{
			"total": 0,
			"list":  refunds,
		})
	}
	count := bson.D{{"$count", "total"}}
	countCursor, err := global.MongoDB.Collection("refunds").Aggregate(context.TODO(), mongo.Pipeline{match, count})
	if err != nil {
		return response.ErrQuery.SetMsg(err.Error())
	}
	var countResult []map[string]interface{}
	if err = countCursor.All(context.TODO(), &countResult); err != nil {
		return response.ErrQuery.SetMsg(err.Error())
	}

	//var refundsExtra []model.RefundWithExtra
	//var refundsExtra []model.Refund
	var refundsExtra []map[string]interface{}
	if len(refunds) > 0 {
		for _, refund := range refunds {
			//refundExtra := model.RefundWithExtra{}
			refundExtra := map[string]interface{}{}
			util.StructAssign(&refundExtra, &refund)
			//b, _ := json.Marshal(refund)
			//json.Unmarshal(b, &refundExtra)
			//refundExtra := &refund

			//global.LoggerOut(len(refundExtra))

			// ------ 订单进度 begin -------
			//global.LoggerOut(refundExtra.ExternalOrderId)
			var refundRefundsProcess *model.RefundRefundProcess
			refundRefundProcess := model.RefundRefundProcess{}

			//filter := bson.D{{"externalOrderId", refundExtra.ExternalOrderId}}
			//filter := bson.D{bson.E{Key: "externalOrderId", Value: refundExtra.ExternalOrderId}}

			filter := bson.D{}
			filter = append(filter, bson.E{Key: "externalOrderId", Value: refundExtra["externalOrderId"]})
			filter = append(filter, bson.E{Key: "trackingNumber", Value: refundExtra["trackingNumber"]})
			match := bson.D{{"$match", filter}}
			sort := bson.D{{"$sort", bson.M{"processDate": -1, "id": -1, "sort": 1}}}
			skip := bson.D{{"$skip", 0}}
			limit := bson.D{{"$limit", 1}}

			var refundProcess []model.RefundProcess
			cursor, err := global.MongoDB.Collection(model.RefundProcess{}.TableName()).Aggregate(context.TODO(), mongo.Pipeline{match, sort, skip, limit})
			if err = cursor.All(context.TODO(), &refundProcess); err != nil {
				return response.ErrQuery.SetMsg(err.Error())
			}
			//global.LoggerOut(len(refundProcess))
			if len(refundProcess) > 0 {
				for _, op := range refundProcess {
					//global.LoggerOut(op.UpdateAt)
					//global.LoggerOut(op.ProcessDate)
					var updateAtOverTime string  // 未跟踪提示
					//if op.UpdateAt.IsZero() {
					//	updateAtOverTime = "未跟踪"
					//} else {
					//	if op.UpdateAt.Add(time.Duration(3) * 24 * time.Hour).Before(time.Now().UTC()) {
					//		updateAtOverTime = "超过3天未跟踪"
					//	} else if op.UpdateAt.Add(time.Duration(1) * 24 * time.Hour).Before(time.Now().UTC()) {
					//		updateAtOverTime = "超过24H未跟踪"
					//	}
					//}

					if op.ProcessDate == "" {
						updateAtOverTime = "未跟踪"
					} else {
						layout := "2006-01-02 15:04:05"
						ProcessAt, _ := time.Parse(layout, op.ProcessDate + " 23:59:59")
						if ProcessAt.Add(time.Duration(3) * 24 * time.Hour).Before(time.Now()) {
							updateAtOverTime = "超过3天未跟踪"
						} else if ProcessAt.Add(time.Duration(1) * 24 * time.Hour).Before(time.Now()) {
							updateAtOverTime = "超过24H未跟踪"
						}
					}

					refundRefundProcess.LastUpdateUser = op.UpdateUser
					refundRefundProcess.LastUpdateAt = op.UpdateAt
					refundRefundProcess.LastProcessDate = op.ProcessDate
					refundRefundProcess.LastProcessContent = op.ProcessContent
					refundRefundProcess.UpdateAtOverTime = updateAtOverTime
					refundRefundsProcess = &refundRefundProcess
					break
				}
			}
			//global.LoggerOut(refundRefundsProcess)
			refundExtra["refundProcess"] = refundRefundsProcess
			// ------ 订单进度 end -------

			refundsExtra = append(refundsExtra, refundExtra)
		}
	}

	return response.OK.WithData(map[string]interface{}{
		"total": countResult[0]["total"],
		//"list":  refunds,
		"list":  refundsExtra,
	})
}

func (r *RefundSrv) FindByID(id uint) response.Resp {
	filter := bson.D{{"id", id}}
	var refund map[string]interface{}
	err := global.MongoDB.Collection("refund").FindOne(context.TODO(), filter).Decode(&refund)
	if err != nil {
		return response.ErrQuery.SetMsg(err.Error())
	}

	return response.OK.WithData(refund)
}

func (r *RefundSrv) Img(ssuid int) response.Resp {
	filter := bson.D{{"ssuid", strconv.Itoa(ssuid)}}
	var refund map[string]interface{}
	err := global.MongoDB.Collection("list_exception_shoot_imgs").FindOne(context.TODO(), filter).Decode(&refund)
	if err != nil {
		return response.ErrQuery.SetMsg(err.Error())
	}

	return response.OK.WithData(refund)
}

func (r *RefundSrv) Detail(req request.RefundDetail) response.Resp {
	filter := bson.D{
		{"shopId", req.ShopId},
		{"returnOrderNumber", req.RefundOrderNumber},
	}
	var refundDetail model.RefundDetail
	err := global.MongoDB.Collection("refund_detail").FindOne(context.TODO(), filter).Decode(&refundDetail)
	if err != nil {
		return response.ErrQuery.SetMsg(err.Error())
	}
	return response.OK.WithData(refundDetail)
}
